refactor(got-patching): extract shared GOT-patching primitives into libdd-got-hook - #2282
Conversation
This stack of pull requests is managed by Graphite. Learn more about stacking. |
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 5509c44 | Docs | Datadog PR Page | Give us feedback! |
63b2fca to
60c1e60
Compare
Artifact Size Benchmark Reportaarch64-alpine-linux-musl
aarch64-unknown-linux-gnu
libdatadog-x64-windows
libdatadog-x86-windows
x86_64-alpine-linux-musl
x86_64-unknown-linux-gnu
|
822405c to
6ab7768
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 822405c2e5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
6ab7768 to
285cdd3
Compare
BenchmarksComparisonBenchmark execution time: 2026-08-04 13:56:13 Comparing candidate commit 5509c44 in PR branch Found 24 performance improvements and 18 performance regressions! Performance is the same for 98 metrics, 0 unstable metrics.
|
978bf00 to
67df7e6
Compare
|
Hey @gyuheon0h cool - this is a good idea! We don't want to end up maintaining N variants of this sort of thing. |
ea56fb3 to
ced5999
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ced5999cd0
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
Nice - I wanted to do this! Will review first thing Monday 💪 Please don't merge beforehand as I'd like to double check all the allocation profiling stuff that rests on it. |
ced5999 to
e9b992a
Compare
|
@yannham @scottgerring Ill just stack another PR on top of this with the new changes, so that this PR strictly only focuses on the initial "no new feature" refactor 👍 |
45c074d to
11a3920
Compare
scottgerring
left a comment
There was a problem hiding this comment.
Hey @gyuheon0h , thanks for taking the time to split this out and make it re-usable! 🙌
Apart from a handful of nits, I think the two things to agree on are the name of the crate (some suggestions inline) and the shape of the API introduced around DynamicInfo
| /// currently-loaded ELF object. | ||
| pub unsafe fn gnu_hash_lookup(info: &DynamicInfo, name: &[u8]) -> Option<Elf64_Sym> { | ||
| let hashtab = info.gnu_hash; | ||
| if hashtab.is_null() || info.gnu_hash_words < 4 { |
There was a problem hiding this comment.
Extra defensive check welcome!
| } | ||
|
|
||
| /// Access to REL relocations (pointer, count). | ||
| pub fn rels(&self) -> (*const Elf64_Rel, usize) { |
There was a problem hiding this comment.
I'm not sure the accessors here are adding much apart from indirection; this is just pushing the unsafe outwards.
I think something like this would be better as it adapts to a safe API and unburdens the caller, but I am also interested in what @yannham thinks:
pub unsafe fn rels(&self) -> Option<&[Elf64_Rel]>.. basically if we're going to change this in the mechanical refactoring bit, we may as well deal with the null check and slice construction in the API itself.
There was a problem hiding this comment.
Yeah, I agree a slice API would be nice. I guess we can even make it safe if the ELF ABI guarantees that a well-formed Elf file will have an array-like layout for self.rels (and check for nulls here).
66e5b36 to
31e53ca
Compare
scottgerring
left a comment
There was a problem hiding this comment.
LGTM! Thanks for addressing comments. Suggest addressing continued feedback on "how we can make this better" in the stacked PR.
Move the ELF parsing, dl_iterate_phdr iteration, PageProtGuard, gnu_hash_symbol_count, gnu_hash_lookup, lookup_symbol, and related utilities out of libdd-profiling-heap-gotter into a new libdd-got-hook crate. libdd-profiling-heap-gotter now depends on libdd-got-hook and keeps only the SymbolOverrides multi-symbol registry and per-library dedup/rescan logic. This is a pure code move — no behavioral changes.
ad0f49a to
cfc1baf
Compare
cfc1baf to
6966e28
Compare
realFlowControl
left a comment
There was a problem hiding this comment.
Had one comment, that might be dd-trace-php specific and is not a blocker to merging this PR.
4542644 to
5509c44
Compare
📚 Documentation Check Results📦
|
🔒 Cargo Deny Results📦
|
…symbol (#2297) Stacked above [refactor(got-patching): extract shared GOT-patching primitives into libdd-got-hook](#2282) Stacked under [feat(crashtracking): retrieve c assert message for linux when __assert_fail is dynamically loaded](#2268) [PROF-15629](https://datadoghq.atlassian.net/jira/software/c/projects/PROF/boards/11?selectedIssue=PROF-15629) # What does this PR do? Adds three general improvements to `libdd-got-hook` for crash tracking (and beneficial to heap profiling): - `DT_HASH` (SysV) fallback: `DynamicInfo::from_phdr` no longer requires `DT_GNU_HASH`. Objects linked with `--hash-style=sysv`are now parsed by reading `nchain` from the SysV hash header. We jjust skipped these objects previously. - Relocation type guard: `elf64_r_type` + `is_got_pointer_reloc` now only patches `GLOB_DAT` and `JUMP_SLOT` relocations (pointer-sized GOT slots) on both `x86_64` and `aarch64`. Non-pointer relocation types are now skipped, preventing potential corruption of adjacent code/data from writing 8 bytes into a 4-byte relocation field. Applied to both `libdd-got-hook`'s `patch_got_entries` and `libdd-profiling-heap-gotter`'s `process_relocation`. (this was a codex recommendation) - `hook_symbol`: Single-symbol convenience wrapper that combines `dlsym` + `iterate_libraries` + `patch_got_entries` into one call. # Motivation What inspired you to submit this pull request? # Additional Notes Gated on @scottgerring's approval # How to test the change? Describe here in detail how the change can be validated. [PROF-15629]: https://datadoghq.atlassian.net/browse/PROF-15629?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ

Stacked under feat(got-hook): add DT_HASH fallback, relocation type guard, and hook_symbol
What does this PR do?
Moves the ELF GOT-patching infrastructure out of libdd-profiling-heap-gotter into a new shared crate libdd-got-hook, so multiple crates can reuse the same machinery for runtime function interposition.
This is a pure code move. I tried to have no behavioral changes here.
What moves to
libdd-got-hookDynamicInfo::from_phdr: parse PT_DYNAMIC from a loaded ELF objectgnu_hash/gnu_hash_symbol_count/gnu_hash_lookup/check_sym: GNU hash table utilitiesiterate_libraries: this is adl_iterate_phdrwrapper with panic-safe trampolinePageProtGuard/read_proc_maps/MapEntry: RELRO-aware page protection managementlookup_symbol/LookupResult: used for resolving a symbol across all loaded objectself64_r_sym: relocation info helperWhat stays in
libdd-profiling-heap-gotterSymbolOverrides: multi-symbol registryhooks.rs: the actualmalloc/free/calloc/reallochook functionsinstall_heap_overrides/update_heap_overridespublic APIMotivation
What inspired you to submit this pull request?
Additional Notes
Gated on @scottgerring's approval
How to test the change?
Describe here in detail how the change can be validated.